﻿// Decompiled with JetBrains decompiler
// Type: Netick.RingBuffer`1
// Assembly: Netick, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 6726ECA1-C773-4CF7-8952-E81B30D93B52
// Assembly location: D:\WorkSpaceDemo\UPM\NetickForUnity\Netick\Runtime\Netick.dll
// XML documentation location: D:\WorkSpaceDemo\UPM\NetickForUnity\Netick\Runtime\Netick.xml

using System;
using System.Collections;
using System.Collections.Generic;

#nullable disable
namespace Netick;

internal class RingBuffer<T> : IEnumerable<T>, IEnumerable
{
  private readonly T[] _elements;
  private int _start;
  private int _end;
  private int _count;
  private readonly int _capacity;

  public T this[int i] => this._elements[(this._start + i) % this._capacity];

  public RingBuffer(int count)
  {
    this._elements = new T[count];
    this._capacity = count;
  }

  public void Add(T element)
  {
    if (this._count == this._capacity)
      throw new ArgumentException();
    this._elements[this._end] = element;
    this._end = (this._end + 1) % this._capacity;
    ++this._count;
  }

  public void FastClear()
  {
    this._start = 0;
    this._end = 0;
    this._count = 0;
  }

  public int Count => this._count;

  public T First => this._elements[this._start];

  public T Last => this._elements[(this._start + this._count - 1) % this._capacity];

  public bool IsFull => this._count == this._capacity;

  public void RemoveFromStart(int count)
  {
    if (count > this._capacity || count > this._count)
      throw new ArgumentException();
    this._start = (this._start + count) % this._capacity;
    this._count -= count;
  }

  public IEnumerator<T> GetEnumerator()
  {
    for (int counter = this._start; counter != this._end; counter = (counter + 1) % this._capacity)
      yield return this._elements[counter];
  }

  IEnumerator IEnumerable.GetEnumerator() => (IEnumerator) this.GetEnumerator();
}
